home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_319 / cnewssrc / uupc.lzh / uupc / dcpsys.c < prev    next >
C/C++ Source or Header  |  1990-01-16  |  19KB  |  876 lines

  1. /*
  2.  *    dcpsys.c
  3.  *
  4.  *    Revised edition of dcp
  5.  *
  6.  *    Stuart Lynne May/87
  7.  *
  8.  *    Copyright (c) Richard H. Lamb 1985, 1986, 1987
  9.  *    Changes Copyright (c) Stuart Lynne 1987
  10.  *
  11.  *    $Id: dcpsys.c,v 1.4 90/01/16 10:25:14 crash Exp Locker: crash $
  12.  */
  13.  
  14. #ifndef lint
  15. static char RCSid[] = "$Id: dcpsys.c,v 1.4 90/01/16 10:25:14 crash Exp Locker: crash $";
  16. #endif /* lint */
  17.  
  18. /*
  19.  *    "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987
  20.  *    Get the next system, and other support routines
  21.  */
  22.  
  23. #include "dcp.h"
  24.  
  25. #ifdef AMIGA
  26. #  include <libraries/dos.h>    /* For TICKS_PER_SECOND */
  27. #endif
  28.  
  29. /*#define PROTOS  "trkg"*/
  30. #define PROTOS          "g"
  31. #define MAXLOGTRY       3
  32.  
  33. Proto Protolst[] = {
  34.     'g', ggetpkt, gsendpkt, gopenpk, gclosepk,
  35. #if 0
  36.         'k', kgetpkt, ksendpkt, kopenpk, kclosepk,
  37.         'r', rgetpkt, rsendpkt, ropenpk, rclosepk,
  38.         't', tgetpkt, tsendpkt, topenpk, tclosepk,
  39. #endif
  40.     '0'};
  41.  
  42. #define EOTMSG "\004\r\004\r"
  43.  
  44. procref         getpkt, sendpkt, openpk, closepk;
  45.  
  46. #ifdef FJE
  47. #define MAXSYS 20
  48. static short sys_cnt = 0;
  49. static char  sys_name[MAXSYS][8];
  50.  
  51. already_called(name)
  52. char *name;
  53. {
  54.     register int i;
  55.  
  56.     for (i=sys_cnt; i-- > 0; )
  57.         if (strncmp(sys_name[i], name, 8) == SAME) return( TRUE );
  58.     return( FALSE );
  59. }
  60. #endif /* FJE */
  61.  
  62. /*
  63.  *    getsystem
  64.  *        Process an "systems" file entry (like "Systems")
  65.  */
  66.  
  67. getsystem()
  68. {
  69.     int    i;
  70.     extern int filecount;            /* From dcpxfer.c */
  71.  
  72. #ifdef FJE
  73.     do {
  74.         if ( fgets( sysline, BUFSIZ, fsys ) == (char *)NULL )
  75.             return( 'A' );
  76.     } while (*sysline == '#' || isspace(*sysline));
  77. #else /* !FJE */
  78.     if ( fgets( sysline, BUFSIZ, fsys ) == (char *)NULL )
  79.         return( 'A' );
  80. #endif /* FJE */
  81.  
  82.     printmsg( 4, "%s", sysline );
  83.     filecount = 0;
  84.     kflds = getargs( sysline, flds );
  85.  
  86.     strncpy( rmtname, flds[FLD_REMOTE], 8 );    /* boake2 */
  87.     rmtname[8] = '\0';
  88.     cctime = flds[FLD_CCTIME];                    /* Any */
  89.     strcpy( device, flds[FLD_DEVICE] );            /* SER: */
  90.  
  91. #if 0
  92.     strcpy( type, flds[FLD_TYPE] );                /* DIR */
  93. #endif
  94.     strcpy( speed, flds[FLD_SPEED] );            /* 2400 or phone# */
  95.     strcpy( proto, flds[FLD_PROTO] );            /* g */
  96.  
  97.     if (debuglevel > 4)
  98.         for (i = FLD_EXPECT; i < kflds; i += 2)
  99.             fprintf( stderr, "expect[%02d]:\t%s\nsend  [%02d]:\t%s\n",
  100.                 i, flds[i], i+1, flds[i+1] );
  101.  
  102.     printmsg( 2, "remote = %s, call time = %s", rmtname, cctime );
  103.     printmsg( 2, "device = %s ", device );
  104.     printmsg( 2, "speed = %s, protocol = %s", speed, proto );
  105.  
  106.     fw = (FILE *)NULL;
  107.     if (
  108.         (checktime( cctime )) ||    /* Any time is okay */
  109.         ( strcmp( Rmtname, "all" ) == SAME ) ||
  110.         ( strcmp( Rmtname, rmtname ) == SAME ) ||
  111.         ( (strcmp( Rmtname, "any" ) == SAME) && scandir() == 'S' )
  112.         ) {
  113.         if ( fw != (FILE *)NULL )
  114.             fclose( fw );            /* in case we matched with scandir */
  115. #ifdef FJE
  116.         if ( already_called( rmtname ) )
  117.             return( 'G' );
  118.         /*
  119.          *    Keep track of the systems we have called so far;
  120.          *    there's no need to call'em twice...
  121.          */
  122.         if (sys_cnt < MAXSYS) {
  123.             strncpy(sys_name[sys_cnt], rmtname, 8);
  124.             sys_name[sys_cnt++][8] = '\0';
  125.         }
  126. #endif
  127.         return( 'S' );                /* startup this system */
  128.     } else
  129.         return('G');
  130. }
  131.  
  132.  
  133. /*
  134.  *    checkname
  135.  *        Do we know the guy ?
  136.  */
  137. checkname(name)
  138. char name[];
  139. {
  140.     FILE *ff;
  141.     char line[BUFSIZ], tmp[20];        /* can change to 8 if %8s works */
  142.  
  143.     if ( ( ff = FOPEN( s_systems, "r", 't' )) == (char *)NULL )
  144.         return( FAILED );
  145.  
  146.     while ( fgets( line, BUFSIZ, ff ) != (char *)NULL ){
  147. #ifdef FJE
  148.         if (*line == '#' || isspace(*line))
  149.             continue;
  150. #endif /* FJE */
  151.         sscanf( line, "%8s ", tmp );
  152.         printmsg( 3, "wanted = %s, found = %s", name, tmp );
  153.         if ( strncmp( tmp, line, 7 ) == SAME ) {
  154.             fclose( ff );
  155.             return ( OK );            /* OK, I like you */
  156.         }
  157.     }
  158.     fclose( ff );
  159.     return( FAILED );                /* Who are you? */
  160. }
  161.  
  162.  
  163. /*
  164.  *    checktime
  165.  *        check if we may make a call at this time
  166.  *        ------------> to be implemented.  Again.  Didn't think it crucial
  167.  */
  168. checktime(xtime)
  169. char    xtime[];
  170. {
  171.     return(0);                        /* OK, go to it */
  172. }
  173.  
  174.  
  175. /*
  176.  *    sysend
  177.  *        end UUCP session negotiation
  178.  */
  179. sysend()
  180. {
  181.     char    msg[80];
  182.  
  183.     msg[1] = '\0';
  184.     msgtime = 2 * MSGTIME;
  185.     wmsg("OOOOOO", 2);
  186.     closeline();
  187.     if ( remote == MASTER )
  188.         return('I');
  189.     return('A');
  190. }
  191.  
  192.  
  193. #if 0
  194. /*
  195.  *    delay
  196.  */
  197. ddelay(dtime)
  198. int    dtime;
  199. {
  200.     int    i, j;
  201.     for (i = 0; i < dtime; )
  202.         i++;
  203. }
  204. #endif
  205.  
  206. /*
  207.  *    wmsg
  208.  *        write a ^P type msg to the remote uucp
  209.  */
  210. wmsg(msg, syn)
  211. int    syn;
  212. char msg[];
  213. {
  214.     int    len;
  215.     len = strlen(msg);
  216.     if (syn == 2)
  217.         swrite("\0\020", 2);
  218.     swrite(msg, len);
  219.     if (syn == 2)
  220.         swrite("\0", 1);
  221. }
  222.  
  223.  
  224. /*
  225.  *    rmsg
  226.  *        read a ^P msg from UUCP
  227.  */
  228.  
  229. rmsg(msg, syn)
  230. int    syn;
  231. char msg[];
  232. {
  233.     int    ii;
  234.     char c, cc[5];
  235.  
  236.     c = 'a';
  237.     if (syn == 2) {
  238.         while ((c & 0x7f) != '\020') {
  239.             if (sread(cc, 1, msgtime) < 1)
  240.                 return(-1);
  241.             /* Don't ask.  MSC needs more than a byte to breathe */
  242.             c = cc[0];
  243.         }
  244.     }
  245.     for (ii = 0; ii < 132 && c ; ii++) {
  246.         if (sread(cc, 1, msgtime) < 1)
  247.             return(-1);
  248.         c = cc[0] & 0x7f;
  249.         if (c == '\r' || c == '\n')
  250.             c = '\0';
  251.         msg[ii] = c;
  252.     }
  253.     return(strlen(msg));
  254. }
  255.  
  256.  
  257. /*
  258.  *    startup
  259.  */
  260. startup()
  261. {
  262.     char    msg[80], tmp1[20], tmp2[20];
  263.     if ( remote == MASTER ) {
  264.         msgtime = 2 * MSGTIME;
  265.         if (rmsg(msg, 2) == -1)
  266.             return('Y');
  267.         printmsg( 2, "1st msg = %s", msg );
  268.         if (msg[5] == '=' && strncmp(&msg[6], rmtname, 7))
  269.             return('Y');
  270.  
  271. #if 0
  272.         /* -Q0 -x16 remote debuglevel set */
  273.         sprintf(msg, "S%.7s -Q0 -x%d", nodename, debuglevel);
  274. #else
  275.         sprintf(msg, "S%.7s", nodename);
  276. #endif
  277.         wmsg(msg, 2);
  278.         if (rmsg(msg, 2) == -1)
  279.             return('Y');
  280.         printmsg( 2, "2nd msg = %s", msg );
  281.         if (strncmp(&msg[1], "OK", 2))
  282.             return('Y');
  283.         if (rmsg(msg, 2) == -1)
  284.             return('Y');
  285.         printmsg( 2, "3rd msg = %s", msg );
  286.         /*
  287.          *    [FJE] Protocol negotiation right here...
  288.          *    Note the "index(..., proto[0])" would become a search
  289.          *        through a list of protocols, looking for the first
  290.          *        which matched, in order of most efficient (?).  Here,
  291.          *        "proto" comes from the Systems file...
  292.          */
  293.         if (msg[0] != 'P' || index(&msg[1], proto[0]) == (char *)NULL) {
  294.             wmsg("UN", 2);
  295.             return('Y');
  296.         }
  297.         sprintf(msg, "U%c", proto[0]);
  298.         wmsg(msg, 2);
  299.         setproto(proto[0]);
  300.         return('D');
  301.     } else {
  302.         msgtime = 2 * MSGTIME;
  303.         sprintf(msg, "Shere=%s", nodename);
  304.         wmsg(msg, 2);
  305.         if (rmsg(msg, 2) == -1)
  306.             return('Y');
  307.         sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2);
  308.         sscanf(tmp2, "-x%d", &debuglevel);
  309.         printmsg( 1, "debug level from remote = %d", debuglevel );
  310.         printmsg( 2, "1st msg from remote = %s", msg );
  311.         if (checkname(rmtname))
  312.             return('Y');
  313.         wmsg("ROK", 2);
  314.         sprintf(msg, "P%s", PROTOS);
  315.         wmsg(msg, 2);
  316.         if (rmsg(msg, 2) == -1)
  317.             return('Y');
  318.         if (msg[0] != 'U' || index(PROTOS, msg[1]) == (char *)NULL )
  319.             return('Y');
  320.         proto[0] = msg[1];
  321.         setproto(proto[0]);
  322.         return('R');
  323.     }
  324. }
  325.  
  326. /******* set the protocol **********/
  327. setproto(pr)
  328. char pr;
  329. {
  330.     int    i;
  331.     Proto *tproto;
  332.  
  333.     for (tproto = Protolst;
  334.             tproto->type != '\0' && pr != tproto->type;
  335.                     tproto++)
  336.         printmsg( 3, "setproto: %c %c", pr, tproto->type );
  337.  
  338.     if (tproto->type == '\0') {
  339.         printmsg( 0,
  340.             "setproto:  You said I had '%c', but I can't find it", pr );
  341.         exit(1);
  342.     }
  343.     getpkt = tproto->a;
  344.     sendpkt = tproto->b;
  345.     openpk = tproto->c;
  346.     closepk = tproto->d;
  347. }
  348.  
  349.  
  350. int prefix(sh, lg)
  351. register char *sh, *lg;
  352. {
  353.     sh--;
  354.     while (*++sh && (*sh == *lg++))
  355.         ;
  356.     return( !*sh );
  357. }
  358.  
  359. int notin(sh, lg)
  360. char *sh, *lg;
  361. {
  362.     while (*lg) {
  363.         if (prefix(sh, lg++))
  364.             return( FALSE );
  365.     }
  366.     return( TRUE );
  367. }
  368.  
  369. #define MAXR 300
  370. unsigned int g_timeout = 30;
  371. static char rdvec[MAXR];
  372.  
  373. int expectstr( str, timeout )
  374. char *str;
  375. int timeout;
  376. {
  377.     char *rp = rdvec;
  378.     int kr;
  379.     char nextch;
  380.  
  381.     printmsg( 2, "wanted :%s:", prt(str, strlen(str)) );
  382.  
  383.     *rp = 0;
  384.     if ( strcmp(str, "\"\"") == SAME )
  385.         return( TRUE );
  386.     while ( notin( str, rdvec ) ) {
  387.         kr = sread( &nextch, 1, timeout /* 40 */ );
  388.         if (kr <= 0) {
  389.             printmsg( 4, "read :%s:", prt(rdvec, rp-rdvec));
  390.             return( FALSE );
  391.         }
  392.         if (*rp = (nextch & 0177))
  393.             *++rp = '\0';
  394.         if (rp >= rdvec + MAXR) {
  395.             printmsg( 4, "read :%s:", prt(rdvec, rp-rdvec));
  396.             return( FALSE );
  397.         }
  398.     }
  399.     printmsg( 3, "read :%s:", prt(rdvec, rp-rdvec));
  400.     return( TRUE );
  401. }
  402.  
  403. int writestr(s)
  404. register char *s;
  405. {
  406.     register char last;
  407.     register char * m;
  408.     int nocr;
  409.  
  410.     last = '\0';
  411.     nocr = FALSE;
  412.     printmsg( 6, "writing <%s>", prt(s, strlen(s)));
  413.     while (*s) {
  414.         if (last == '\\') {
  415.             switch (*s) {
  416.             case 'p':            /* 1/2 second pause */
  417.             case 'P':
  418.                 ticks( (long) TICKS_PER_SECOND >> 1 );
  419.                 break;
  420.             case 'd':
  421.             case 'D':            /* delay */
  422.                 sleep(2);
  423.                 break;
  424.             case 'k':            /* Break signal */
  425.             case 'K':
  426.                 ssendbrk(3);
  427.                 break;
  428.             case 'c':
  429.             case 'C':            /* end string don't output CR */
  430.                 nocr = TRUE;
  431.                 break;
  432.             case 'r':
  433.             case 'R':            /* carriage return */
  434.             case 'm':
  435.             case 'M':
  436.                 swrite( "\r", 1 );
  437.                 break;
  438.             case 'n':
  439.             case 'N':            /* newline */
  440.                 swrite( "\n", 1 );
  441.                 break;
  442.             case 'b':
  443.             case 'B':            /* backspace */
  444.                 swrite( "\b", 1 );
  445.                 break;
  446.             case 't':
  447.             case 'T':            /* tab */
  448.                 swrite( "\t", 1 );
  449.                 break;
  450.             case 's':
  451.             case 'S':            /* space */
  452.                 swrite( " ", 1 );
  453.                 break;
  454.             case 'w':    /* Set the delay time for expect strings */
  455.             case 'W':    /* up to 120 seconds (2 minutes) */
  456.                 g_timeout = 0;
  457.                 for (s++; isdigit(*s); )
  458.                     g_timeout = g_timeout*10 + (*s++ - '0');
  459.                 if (g_timeout > 120)
  460.                     g_timeout = 30;
  461.                 s--;
  462.                 break;
  463.             case 'z':    /* Set the baud rate... */
  464.             case 'Z':
  465.                 SIOSpeed( ++s );
  466.                 while ( *s != '\0' && *s != '\\' )
  467.                     s++;
  468.                 if ( *s == '\\' )
  469.                     s++;
  470.                 break;
  471.             default:
  472.                 swrite( s, 1 );
  473.             }
  474.             last = '\0';
  475.         } else if (*s != '\\') {
  476.             swrite( s, 1 );
  477.         } else
  478.             last = *s;
  479.         s++;
  480.     }
  481.     return( nocr );
  482. }
  483.  
  484. /***
  485.  *   void sendthem(str)   send line of login sequence
  486.  *         char *str;
  487.  *
  488.  *   return codes:  none
  489.  */
  490.  
  491. void sendstr(str)
  492. char *str;
  493. {
  494.     int nw, ns;
  495.     long nulls;
  496.  
  497.     printmsg( 2, "sending %s", str );
  498.  
  499.     if (prefix("BREAK", str)) {
  500.         sscanf(&str[5], "%1d", &nulls);
  501.         if (nulls <= 0 || nulls > 10)
  502.             nulls = 3;
  503.         /* send break */
  504.         ssendbrk(nulls);
  505.         return;
  506.     }
  507.     if ( strcmp(str, "EOT") == SAME ) {
  508.         swrite(EOTMSG, strlen(EOTMSG));
  509.         return;
  510.     }
  511.     if ( strcmp(str,"\"\"") == SAME )
  512.         *str = '\0';
  513.  
  514.     if ( strcmp(str,"") != SAME ) {
  515.         if (!writestr(str))
  516.             swrite ("\r", 1);
  517.     } else
  518.         swrite("\r", 1);
  519.     return;
  520. }
  521.  
  522. int sendexpect( s, e, timeout )
  523. char *s;
  524. char *e;
  525. int timeout;
  526. {
  527.     sendstr( s );
  528.     return( expectstr( e, timeout ) );
  529. }
  530.  
  531. dial()
  532. {
  533.     int    flg, kk, jj, ll, firstflg;
  534.     char buf[4], *prsend;
  535.     char *exp;
  536.     char *alternate;
  537.     int    ok;
  538.     int i;
  539.  
  540.     if ( strcmp( flds[FLD_TYPE], "HAYES" ) != SAME ) {
  541.         printmsg( 0, "dial: unsupported dialer %s", flds[FLD_TYPE] );
  542.         return( FALSE );
  543.     }
  544.     printmsg( 3, "calling host %s", rmtname );
  545.     if (openline(device, "2400" ))
  546.         return( FALSE );
  547.  
  548.     printmsg( 0, "hayes: trying 2400" );
  549.     if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) {
  550.         sendexpect( "\\d+++\\d", "OK", 2 );
  551.         if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) {
  552.             printmsg( 0, "hayes: trying 1200" );
  553.             SIOSpeed( "1200" );
  554.             if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) {
  555.                 sendexpect( "\\d+++\\d", "OK", 2 );
  556.                 if ( sendexpect( "ATZ", "OK", 2 ) != TRUE )
  557.                     return( FALSE);
  558.             }
  559.         }
  560.     }
  561.     printmsg( 0, "hayes: got modem response" );
  562.     /*
  563.      *    DO NOT REMOVE THE \d FROM THE LINE BELOW!!!
  564.      *
  565.      *    My SupraModem seemed pretty critical about returning an "OK"
  566.      *    response but not really being interested in user commands for
  567.      *    another second or so.  And since \d is about 2 seconds...
  568.      */
  569.     sendexpect( "ATX4\\r\\d", "OK\n\r", 2 );
  570.     printmsg( 4, "attempting to dial :%s:", speed );
  571.  
  572. #ifdef FJE
  573.     sendstr( speed );
  574.     /*
  575.      *    Typical character stream after the command to dial:
  576.  
  577.          AT DT 123-4567\n        -- computer sends this, and gets back...
  578.  
  579.          AT DT 123-4567\r
  580.          (pauses while dialing; waiting for carrier)
  581.          \nCONNECT xx00\r\n
  582.  
  583.      */
  584.     if (expectstr( "\r", 10 ) != TRUE) {    /* eat echoing of dial command */
  585.         printmsg(1, "hayes: modem not responding after reset!?\n");
  586.         return( FALSE );
  587.     }
  588.     if (expectstr("\n", 50) != TRUE) {
  589.         printmsg(1, "hayes: modem not responding after dial command!?\n");
  590.         return( FALSE );
  591.     }
  592.     if (expectstr("\r\n", 6) != TRUE) {
  593.         printmsg(1, "hayes: didn't get expected response [%s]",
  594.              prt(rdvec, strlen(rdvec)));
  595.     }
  596.     /*
  597.      *    This block used to be part of the above "if" stmt...
  598.      */
  599.     {
  600.         register char *resp = rdvec, *prt();
  601.         extern int atoi();
  602.  
  603.         if (strnicmp( resp, "BUSY", 4 ) == SAME) {
  604.             printmsg(1, "hayes: BUSY -- phone line busy\n");
  605.             return( FALSE );
  606.         } else if (strnicmp( resp, "NO DIALTONE", 11 ) == SAME) {
  607.             printmsg(1, "hayes: NO DIALTONE -- check phone line\n");
  608.             return( FALSE );
  609.         } else if (strnicmp( resp, "NO CARRIER", 10 ) == SAME) {
  610.             printmsg(1, "hayes: NO CARRIER -- answered, but no carrier\n");
  611.             return( FALSE );
  612.         } else if (strnicmp( resp, "NO ANSWER", 9 ) == SAME) {
  613.             printmsg(1, "hayes: NO ANSWER -- call not answered\n");
  614.             return( FALSE );
  615.         } else if (strnicmp( resp, "CONNECT", 7 ) == SAME) {
  616.             printmsg( 3, "hayes: got CONNECT" );
  617.             if (atoi(resp+8)) {
  618.                 printmsg( 3, "hayes: speed select %s",
  619.                     prt(resp+8,strlen(resp+8)) );
  620.                 SIOSpeed( resp+8 );
  621.             }
  622.         } else {
  623.             printmsg(1, "hayes: unknown modem response!  [%s]\n",
  624.                  prt(resp, strlen(resp)));
  625.             return( FALSE );
  626.         }
  627.     }
  628. # if 0
  629.     else {
  630.         printmsg(1, "hayes: modem not responding to dial command!? [%s]\n",
  631.             prt(rdvec, strlen(rdvec)));
  632.         return( FALSE );
  633.     }
  634. # endif
  635. #else /* !FJE */
  636.     if ( sendexpect( speed, "CONNECT", 40 ) != TRUE ) {
  637.         printmsg( 0, "hayes: no answer");
  638.         return( FALSE );
  639.     }
  640.     printmsg( 3, "hayes: got CONNECT" );
  641.     if ( sread( buf, 5, 5 ) == 5 ) {
  642.         printmsg( 3, "hayes: speed select %s", buf );
  643.         /* set speed appropriately */
  644.         SIOSpeed( buf );
  645.     }
  646. #endif
  647.     return( TRUE );
  648. }
  649.  
  650.  
  651. /*
  652.  *    callup
  653.  *        script processor - nothing fancy!
  654.  */
  655. callup()
  656. {
  657.     int    flg, kk, jj, ll, firstflg;
  658.     char *prsend;
  659.  
  660.     char *exp;
  661.     char *alternate;
  662.     int    ok;
  663.     int i;
  664.  
  665.     printmsg( 0, "calling host %s", rmtname );
  666.  
  667.     if ( strcmp( flds[FLD_TYPE], "DIR" ) != SAME ) {
  668.         if ( dial() == FALSE )
  669.             return( 'G' );
  670.     } else if (openline(device, speed))
  671.         return( 'G' );
  672.  
  673.     for (i = 6; i < kflds; i+=2) {
  674.         exp = flds[i];
  675.         printmsg( 3, "callup: expect %d of %d  \"%s\"", i, kflds, exp );
  676.         ok = FALSE;
  677.         while (ok != TRUE) {
  678.             alternate = index( exp, '-' );
  679.             if (alternate != (char *)NULL)
  680.                 *alternate++ = '\0';
  681.  
  682.             ok = expectstr( exp, g_timeout );
  683.             printmsg( 3, "got %s", ok != TRUE ? "?" : "that" );
  684.             if ( ok == TRUE )
  685.                 break;
  686.             if ( alternate == (char *)NULL ) {
  687.                 printmsg( 0, "LOGIN FAILED" );
  688.                 return( 'Y' );
  689.             }
  690.             exp = index( alternate, '-' );
  691.             if ( exp != (char *)NULL )
  692.                 *exp++ = '\0';
  693.  
  694.             printmsg( 3, "send alternate" );
  695.             sendstr( alternate );
  696.         }
  697.         printmsg(3, "callup: send %d of %d \"%s\"", i+1,kflds, flds[i+1]);
  698.         sleep(1);
  699.         sendstr(flds[i+1]);
  700.     }
  701.     return('P');
  702. }
  703.  
  704. #if 0
  705. /*
  706.  *    slowrite
  707.  *        comunication slow write.  needed for auto-baud modems
  708.  */
  709. slowrite(st)
  710. register char *st;
  711. {
  712.     int    len, j;
  713.     char c;
  714.  
  715.     len = strlen(st);
  716.     printmsg( 3, "sent %s", st );
  717.     for (j = 0; j < len; j++) {
  718.         swrite(&st[j], 1);
  719.         ddelay(80000);
  720.     }
  721. }
  722. #endif
  723.  
  724. /*
  725.  *    scandir
  726.  */
  727.  
  728. #include "ndir.h"
  729.  
  730. #define Direct    struct direct
  731.  
  732. dcmp(a, b)
  733. Direct *a, *b;
  734. {
  735.     return( strcmp(b->d_name, a->d_name) );
  736. }
  737.  
  738. /*
  739.  *    scandir
  740.  *        scan work dir for C. files matching current remote host (rmtname)
  741.  *
  742.  *    [FJE] There's foom for optimization here:  cache the directory entries
  743.  *        so we don't have to search again.  Primarily an advantage when
  744.  *        running off of floppies.  Same goes for "dscandir()", below.
  745.  *    [FJE] The directory caching has been implemented.  It even worked
  746.  *        first try!!!  There _MUST BE_ something wrong!
  747.  *
  748.  *    return:
  749.  *        A    - abort, couldn't open directory
  750.  *        Y    - at least one file exists, but can't open it
  751.  *        S    - at least one file found, FILE * in "fw"
  752.  *        Q    - no files that match
  753.  */
  754.  
  755. scandir()
  756. {
  757.     int    fn, len, i;
  758.     char cname[40], tmp[132];
  759.  
  760.     DIR *dirp;
  761.     struct direct *dp;
  762.  
  763. #ifdef FJE
  764.     static Direct *cache = 0, *malloc(), *realloc();
  765.     static short count;
  766.  
  767.     if (count) {
  768.         strcpy(cfile, cache[--count].d_name);
  769.         printmsg( 3, "scandir: uncaching %s", cfile );
  770.         return( -1 );
  771.     } else {
  772.         if (cache)    free(cache);
  773.         cache = malloc(sizeof(Direct));
  774.         count = 0;
  775.     }
  776. #endif /* FJE */
  777.     if ((dirp = opendir( spooldir )) == (DIR *)NULL ) {
  778.         fprintf( stderr, "couldn't open dir %s\n", spooldir );
  779.         return( 'A' );
  780.     }
  781.     sprintf(cname, CALLFILE, rmtname);
  782.     len = strlen(cname);
  783.     while ((dp = readdir(dirp)) != (struct direct *)NULL) {
  784.         if (strnicmp(cname, dp->d_name, len) == SAME) {
  785. #ifndef FJE
  786.             printmsg( 3, "scandir: file = %s", dp->d_name );
  787.             strcpy(cfile, dp->d_name);
  788.             closedir( dirp );
  789.             if ((fw = FOPEN( cfile, "r", 't' )) == (char *)NULL )
  790.                 return('Y');
  791.             return('S');
  792. #else
  793.             if ((count % 8) == 0)
  794.                 cache = realloc(cache, sizeof(Direct) * (count+8));
  795.             strcpy(cache[count++].d_name, dp->d_name);
  796.             printmsg( 3, "scandir: caching %s", dp->d_name );
  797. #endif /* FJE */
  798.         }
  799.     }
  800.     closedir( dirp );
  801. #ifdef FJE
  802.     if (count) {
  803.         qsort(cache, count, sizeof(Direct), dcmp);
  804.         strcpy(cfile, cache[--count].d_name);
  805.         printmsg(3, "scandir: %hd files; uncaching %s", count+1, cfile);
  806.         return( -1 );
  807.     }
  808. #endif /* FJE */
  809.     return('Q');
  810. }
  811.  
  812. /*
  813.  *    dscandir -- looks for X.<rmtname> files
  814.  *        scan the directory, [FJE] using a cache of the current
  815.  *        contents.  When the cache is empty, the directory is scanned
  816.  *        again to see if anything new has come in.
  817.  *
  818.  *    returns:
  819.  *        ret(0) if no $SPOOLDIR or no X. files in $SPOOLDIR
  820.  *        ret(-1) if at least one file found
  821.  */
  822.  
  823. dscandir()
  824. {
  825.     int    fn, len, i;
  826.     char cname[40], tmp[132];
  827.     DIR *dirp;
  828.     Direct *dp;
  829.  
  830. #ifdef FJE
  831.     static Direct *cache = 0, *malloc(), *realloc();
  832.     static short count;
  833.  
  834.     if (count) {
  835.         strcpy(cfile, cache[--count].d_name);
  836.         printmsg( 3, "dscandir: uncaching %s", cfile );
  837.         return( -1 );
  838.     } else {
  839.         if (cache)    free(cache);
  840.         cache = (Direct *) malloc(sizeof(Direct));
  841.         count = 0;
  842.     }
  843. #endif /* FJE */
  844.     if ((dirp = opendir( spooldir )) == (DIR *)NULL ) {
  845.         fprintf( stderr, "couldn't open dir %s\n", spooldir );
  846.         return(0);
  847.     }
  848.     sprintf(cname, XQTFILE, rmtname);
  849.     len = strlen(cname);
  850.     while ((dp = readdir(dirp)) != (Direct *)NULL) {
  851.         if ( strnicmp( cname, dp->d_name, len ) == SAME ) {
  852. #ifndef FJE
  853.             printmsg( 3, "dscandir: file = %s", dp->d_name );
  854.             strcpy(cfile, dp->d_name);
  855.             closedir( dirp );
  856.             return( -1 );
  857. #else
  858.             if ((count % 8) == 0)
  859.                 cache = realloc(cache, sizeof(Direct) * (count+8));
  860.             strcpy(cache[count++].d_name, dp->d_name);
  861.             printmsg( 3, "dscandir: caching %s", dp->d_name );
  862. #endif /* FJE */
  863.         }
  864.     }
  865.     closedir( dirp );
  866. #ifdef FJE
  867.     if (count) {
  868.         qsort(cache, count, sizeof(Direct), dcmp);
  869.         strcpy(cfile, cache[--count].d_name);
  870.         printmsg(3, "dscandir: %hd files; uncaching %s", count+1, cfile);
  871.         return( -1 );
  872.     }
  873. #endif /* FJE */
  874.     return( 0 );
  875. }
  876.